Skip to content

[cicd-80/e2e] GitHub Actions E2E 테스트 워크플로우 추가 - #209

Merged
hm1n merged 12 commits into
developfrom
hm1n/e2e-test-case
Sep 2, 2026
Merged

[cicd-80/e2e] GitHub Actions E2E 테스트 워크플로우 추가#209
hm1n merged 12 commits into
developfrom
hm1n/e2e-test-case

Conversation

@hm1n

@hm1n hm1n commented Sep 1, 2026

Copy link
Copy Markdown
Collaborator

Summary

3줄 이내로 이번 PR을 요약합니다.

Notion 테스트 시나리오 DB의 P0 15건을 Playwright 테스트 코드로 작성했습니다.
developmain 대상 PR에서 이 테스트를 실행하는 GitHub Actions 워크플로우를 추가했습니다.
구현 설계서 v2의 Task 6(#210)과 Task 7(#211)에 해당합니다.


Why

왜 이 작업을 진행했나요?

  • 자동화 대상 135건을 문서화하고 우선순위를 확정했으나 코드로 옮겨진 것이 없어, 배포 전 회귀 확인을 여전히 사람이 브라우저에서 직접 하고 있었습니다.
  • Task 5([test-78/e2e] 인증 및 테스트 데이터 준비 구조 작성 #208)에서 세션 주입과 seed 구조를 마쳐, P0 15건 중 13건이 전제로 하는 로그인 상태를 만들 수 있게 되었습니다. 코드 작성을 막고 있던 제약이 사라졌습니다.
  • 테스트가 있어도 실행이 자동화되지 않으면 수동 확인이 이름만 바뀐 것과 같아, CI 게이트까지 한 번에 붙였습니다.

Decision

어떤 구현 방식을 선택했나요?

선택한 구현 방식

  • 문서 구조를 코드 구조에 대응시켰습니다. spec 파일은 도메인, describe는 시나리오, test는 케이스 하나이고 각 test 위 주석이 Notion ID입니다.
  • 소셜 로그인 화면은 자동화하지 않고, Supabase에서 세션을 발급받아 브라우저 localStorage에 주입하고 시작합니다.
  • CI는 next dev가 아니라 빌드 결과(next start)를 실행합니다.

검토한 대안

  • 선택자를 기존 Tailwind class와 DOM 구조로 짚는 방법
  • CI를 developmain 단계에서만 실행하는 방법
  • 세션 저장 형식을 테스트가 직접 만들어 넣는 방법

선택 이유

  • class와 DOM 구조 기반 선택자는 추가 변경이 없지만 스타일이나 마크업을 조금만 고쳐도 깨집니다. data-testid는 변경 범위가 넓은 대신 UI 구조 변경에 견딥니다.
  • 단계를 뒤로 미루면 여러 PR이 합쳐진 뒤 실패해 원인을 좁히기 어렵고, 릴리즈가 막힌 상태에서 조사하게 됩니다. 매 PR 실행은 실패 범위를 한 PR로 한정합니다.
  • 세션 직렬화는 supabase 클라이언트가 하도록 두고 결과만 옮기므로, 라이브러리 저장 형식이 바뀌어도 테스트가 따라 깨지지 않습니다.

Changes

무엇이 변경되었나요?

Feature

  • 없습니다. 제품 동작 변경은 없습니다.

Fix

  • 테스트 계정 생성 시 taguser_tag_key 유니크 제약과 충돌하면 다른 값으로 다시 시도하도록 수정했습니다.

Refactor

  • data-testid 9개를 제품 코드에 추가했습니다. className, DOM 구조, 로직은 바꾸지 않았습니다.
  • Checkbox에 선택 prop testId를 추가했습니다. 넘기지 않으면 속성이 렌더되지 않습니다.

Test

  • P0 15건을 e2e/{auth,group,invite,settlement}.spec.ts로 작성했습니다.
  • 공용 fixture를 작성했습니다: env, seed, session, ui, test
  • Playwright 프로젝트를 mobile(Pixel 5)과 desktop(Desktop Chrome)으로 분리했습니다.
  • CI에서 빌드 서버를 실행하고 워커를 2로 올리도록 설정을 분기했습니다.
  • e2e 디렉터리에 @typescript-eslint/no-floating-promises를 적용하고 next lint 범위를 넓혔습니다.

Docs

  • .github/workflows/ci-e2e-test.yml을 추가했습니다.
  • e2e/README.md에 실행 준비, 인증 방식, 뷰포트, CI 절차를 정리했습니다.
  • 정산 기록 갱신 오류 재전파 사례를 llm-wiki/raw에 보존했습니다.

Trade-off

한계와 트레이드오프

  • 세션 주입은 로그인 이후 로직 검증에는 강하지만, redirect URI 오설정이나 OAuth 클라이언트 설정 오류처럼 실제 Provider 연동이 어긋나는 문제는 잡지 못합니다. 낮은 빈도의 수동 확인으로 보완해야 합니다.
  • 제품 코드에 테스트 전용 속성이 들어갔습니다. 렌더 결과는 그대로지만 소스에 테스트 관심사가 섞입니다.
  • 테스트 계정을 재사용하지 않고 실행마다 23개를 만들고 지웁니다. 격리는 확실하지만 인증 API 호출이 늘어납니다.
  • 커버하는 범위는 135건 중 15건입니다. P1 이하 120건은 이후 작업입니다.
  • 정산 기록 갱신 실패 시 컴포넌트가 PostgrestError 객체를 다시 던져 메시지 없는 unhandled rejection이 남습니다. API route 이관 시 구체화하기로 하고 이번에는 사용자에게 보이는 결과만 검증합니다.

수용한 보안 지적

service role key가 PR 코드와 같은 환경에서 실행됩니다

Codex 리뷰에서 P1으로 지적된 내용이며, 메커니즘은 사실로 확인했습니다.

pull_request 이벤트는 제안된 병합 커밋의 코드를 실행합니다. 테스트 단계는 그 코드를 SUPABASE_SERVICE_ROLE_KEY가 든 환경에서 돌리므로, 브랜치 PR을 열 수 있는 사람은 리뷰 전에 키를 외부로 보내는 코드를 넣을 수 있습니다. fork PR을 배제한 설정은 이 경로를 막지 못합니다. 공격자가 fork가 아니라 같은 저장소의 브랜치를 쓰기 때문입니다.

이번 PR에서는 수용하고 #212로 분리했습니다. 근거는 다음과 같습니다.

항목 현재 상태
노출되는 값 E2E_SUPABASE_SECRET_KEY 하나입니다. publishable key와 URL은 공개를 전제로 한 값입니다
대상 프로젝트 운영과 분리된 개발 Supabase입니다. 실제 고객 데이터가 없습니다(user 행 4개)
악용 가능한 사람 조직에 push 권한이 있는 사람으로 한정됩니다. 외부인은 불가능합니다
유출 시 피해 개발 DB의 RLS 우회입니다. 운영에는 닿지 않습니다

검토했으나 선택하지 않은 대안

  • GitHub Environment 필수 승인자: 노출은 막지만 매 PR마다 수동 승인이 생깁니다. 자동 게이트를 도입하는 이 PR의 목적과 정면으로 부딪힙니다.
  • 개발 DB와 분리된 테스트 전용 프로젝트: 잃을 데이터는 줄지만, 저장소 쓰기 권한이 해당 프로젝트 전권으로 이어지는 구조는 그대로입니다.

권한 자체를 좁히는 것만이 구조를 바꾸므로 #212에서 다룹니다. 다만 이 판단은 "개발 DB에 지킬 데이터가 없다"는 전제에 기대고 있습니다. 참여 인원이 늘거나 개발 DB에 의미 있는 데이터가 쌓이면 #212의 우선순위를 올려야 합니다.


Impact

기존 기능에 미치는 영향

  • 영향받는 기능: 없습니다. 제품 코드 변경은 data-testid 속성 추가와 Checkbox의 선택 prop 추가뿐이고, 렌더 결과와 동작은 동일합니다.
  • 회귀 가능성이 있는 영역: Checkbox는 참여자 카드와 약관 동의 폼이 함께 사용합니다. testId를 넘기지 않는 약관 동의 폼에는 속성이 렌더되지 않는 것을 확인했습니다.
  • 배포 시 확인할 사항: 제품 번들에 영향이 없어 배포 시 별도 확인 사항은 없습니다. 다만 이 PR 이후 develop 대상 모든 PR에 E2E 게이트가 걸립니다.
  • 테스트는 개발 DB를 사용합니다. 만든 데이터는 실행 후 되돌리며, 잔여 0건을 확인했습니다.

Edge Cases

Edge Case 및 실패 시나리오

  • 테스트 계정 tag 충돌: 네 자리 난수라 실행당 약 3% 확률로 유니크 제약에 걸립니다. 실제로 발생했고 재시도로 해결했습니다.
  • 개발 서버의 경로별 컴파일: 기본 타임아웃과 병렬 워커로는 7건이 실패했습니다. CI는 빌드 서버를 써서 이 문제가 없습니다.
  • Secret 이름 오타: 값이 빈 문자열로 들어오면 테스트가 실패가 아니라 건너뛴 채 초록으로 끝납니다. Check secrets 단계로 빌드 전에 멈춥니다.
  • 충돌 중인 PR: pull_request 이벤트는 병합 커밋 위에서 실행되므로 충돌이 있으면 워크플로우가 아예 돌지 않습니다. 실패로 보이지도 않습니다.
  • 납부 상태 저장 실패: 요청을 500으로 가로채 토스트가 뜨고 체크박스가 원래 상태를 유지하는지 검증합니다.

Review Points

리뷰어가 집중해서 봐야 할 부분

🔴 High

  • data-testid 위치: 조회 카드는 값 div에, 편집 카드는 입력 요소에 붙였습니다. 컴포넌트 소유자 관점에서 어색한 곳이 있는지 봐주세요.
  • 세션 주입과 service role key 취급: key가 브라우저로 넘어가지 않는지, seed와 cleanup 범위가 안전한지 확인이 필요합니다.

🟡 Medium

  • 뷰포트 정책: develop은 모바일만, main에서 PC를 추가합니다. 이 분배가 맞는지 판단이 필요합니다.
  • retries: 2: 실행이 짧아져 재시도 비용은 작지만, 재시도가 성공하면 간헐 실패가 결과에 묻힙니다. 1로 낮출지 의견을 주세요.
  • Secrets 이름: E2E_ 접두어에 Supabase 현재 명칭(publishable/secret)을 붙였습니다. 앱 환경변수 이름은 그대로 두고 워크플로우 env에서 연결합니다.

🟢 Low

  • CheckboxtestId prop: 선택 prop을 추가하는 방식이 적절한지 봐주세요.
  • e2e 한정 lint 규칙: react-hooks/rules-of-hooks를 껐습니다. Playwright fixture 인자 이름이 use라 오탐이 납니다.

Validation

어떻게 검증했나요?

  • 단위 테스트
  • E2E 테스트
  • 수동 테스트
  • lint
  • typecheck

실행 결과

  • 모바일 16/16 통과, PC 16/16 통과
  • CI 러너 실행 통과 (job 2분 29초, 테스트 단계 37초)
  • env 파일을 모두 치우고 워크플로우가 주입하는 값만으로 빌드와 테스트 통과. 러너와 같은 조건입니다
  • 실행 후 개발 DB 잔여 데이터 0건
  • eslint e2e exit 0, prettier 통과

확인하지 못한 것

  • upload-artifact는 실패 시에만 도는 단계라 이번 성공 실행으로는 검증되지 않았습니다.
  • main 대상 PR의 PC 뷰포트 matrix는 아직 실제로 실행된 적이 없습니다.

hm1n and others added 10 commits August 28, 2026 19:20
10개 도메인(인증, 랜딩페이지, 그룹, 초대, 정산, 채팅, 커뮤니티, 알림,
친구, 마이페이지)의 테스트 케이스 초안 143건을 output에 남긴다.

raw에는 두 건의 작업 원본을 함께 보존한다.

- CI 속성 삭제와 Test Guide 재작성 배경
- 도메인별 초안 작성 과정, 그리고 검토용으로 위임한 에이전트가 승인 없이
  Notion에 push한 사고의 경위와 사후 처리

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Notion Test Guide와 테스트 시나리오 DB 136건을 실측해 문서와 데이터가
어긋난 부분을 정리했고, 그 과정과 결과를 llm-wiki에 남긴다.

문서 개정
- 시나리오 판정 기준과 ID 작성 규칙을 새로 정의
- 속성별 필수 여부와 기본값을 명시하고 실제 스키마 이름에 맞춤
- 에이전트 작업 경계 절 신설
- 줄바꿈이 리터럴 n으로 깨져 있던 실패 진단 정책 절 복구
- 설계서 v2의 CI 실행 범위 서술을 Test Guide 기준으로 정정

DB 정리
- 시나리오 129개를 43개로 재정리하고 ID 117건을 3세그먼트로 재부여
- 자동화 상태 135건, 테스트 레벨 공백 73건을 채움
- 회귀 28건 재분류, Smoke 8건을 태그로 이관
- TEMPLATE-000을 일반 페이지로 분리하고 폐기 select 옵션 제거
- 우선순위를 P0 15, P1 35, P2 72, P3 13으로 재배정

결정 기록
- 도메인은 단일 select를 유지한다. 도메인 분류보다 시나리오와 케이스
  내용이 중요하고, 도메인이 spec 파일을 결정하기 때문이다
- 우선순위 판정 기준은 이 검증이 없을 때 사용자가 무엇을 잃는가로 둔다

수정 전 원본 두 건도 롤백용으로 함께 보존한다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
E2E 테스트가 금액, 참여 인원, 납부 체크박스를 짚을 때 Tailwind 클래스와
XPath에 의존하고 있었다. 디자인을 수정하면 테스트가 함께 깨지므로 role이나
텍스트로 짚을 수 없는 지점에만 data-testid를 붙인다.

- 엔빵 조회 카드의 총 금액, 참여 인원, 엔빵 금액, 정기 결제일 값
- 엔빵 생성 폼의 참여 인원, 엔빵 금액, 정기 결제일 입력
- 참여자 카드와 납부 체크박스

Checkbox는 공용 컴포넌트라 testId를 선택 prop으로 받게 한다. 값을 넘기지
않으면 data-testid 자체가 렌더되지 않아 기존 사용처의 출력은 그대로다.

className과 DOM 구조는 바꾸지 않았다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Notion 테스트 시나리오 DB에서 P0로 배정한 15건을 코드로 옮긴다. spec 파일은
도메인 단위, describe는 시나리오 단위, test는 케이스 하나에 대응하고 각 test
위의 주석이 Notion ID다.

- auth 2건: 비로그인 보호 경로 차단, 로그인 콜백 복귀 경로
- group 5건: 그룹 생성 3건, 홈에서 상세 진입, 참여자 수정 권한 차단
- invite 2건: 초대 링크 조회, 초대 수락
- settlement 6건: 납부 상태 변경 3건, 정산 기간 기록 2건, 저장 실패

공용 fixture
- 세션은 Supabase 클라이언트를 메모리 저장소로 만들어 로그인시킨 뒤
  라이브러리가 기록한 항목을 그대로 브라우저에 옮긴다. 저장 형식이 바뀌어도
  테스트가 따라 깨지지 않는다
- seed는 테스트가 만든 사용자, 그룹, 참여자, 초대, 정산 기록을 추적해 실패해도
  되돌린다. service role key는 Node helper에서만 쓰고 브라우저로 넘기지 않는다
- 테스트 계정 비밀번호는 E2E_TEST_USER_PASSWORD 환경변수로 받는다

next dev가 경로마다 첫 진입에서 컴파일하는 탓에 기본 타임아웃과 병렬 워커로는
7건이 실패했다. 타임아웃을 90초와 20초로 올리고 워커를 1개로 고정한다. 병렬
3.5분 7실패에서 직렬 2.7분 전건 통과로 바뀌었다.

개발 DB를 대상으로 16건 전부 통과하고, 실행 후 잔여 데이터가 없음을 확인했다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Playwright 테스트는 await가 빠져도 어설션이 조용히 통과한다. 타입 정보를 켜고
잡도록 e2e에만 규칙을 켠다.

next lint는 기본으로 src만 훑어서 e2e가 한 번도 린트되지 않고 있었다. lint
스크립트에 대상 디렉터리를 명시한다.

fixture 인자 이름 use가 React Hook으로 오인되는 문제가 있어 같은 범위에서만
rules-of-hooks를 끈다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
납부 상태 저장이 실패하면 참여자 카드가 토스트를 띄운 뒤 오류를 다시 던진다.
던지는 값이 Error가 아니라 PostgrestError 객체라 브라우저에는 메시지 없는
처리되지 않은 거부만 남고, 오류 추적에 쓸 정보가 사라진다.

사용자에게 보이는 동작은 정상이라 지금은 고치지 않는다. 정산 기록 갱신을 API
route로 옮길 때 오류를 구체화하기로 했고, 그때 근거로 쓸 수 있도록 확인한
내용과 재현 방법을 raw에 남긴다.

log.md에는 P0 구현 과정과 Notion 자동화 상태 갱신 결과를 함께 기록한다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
develop에 추가된 gh-commit 스킬이 이 브랜치에는 없어 커밋 작업에서 쓸 수
없었다. 해당 경로만 develop에서 가져온다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Seeder.createUser가 tag를 네 자리 난수로 뽑는데 user_tag_key 유니크 제약이
걸려 있다. 한 번 실행에 계정을 23개 만들기 때문에 실행당 약 3% 확률로
23505 duplicate key로 실패한다. 다섯 번째 실행에서 실제로 나왔다.

user 행 삽입을 insertUserRow로 분리하고 tag 충돌일 때만 최대 열 번까지
다른 값으로 다시 시도한다. 다른 오류는 그대로 던진다.

가입 트리거가 user 행을 만들 수 있다는 기존 주석은 사실과 달라 함께 고쳤다.
인증 사용자를 만든 직후 user 행이 없음을 확인했고, 이 helper가 유일한
생성 경로다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
서비스가 모바일 우선인데 지금까지 Desktop Chrome으로만 검증했다. 프로젝트를
mobile과 desktop 둘로 나눠 평소에는 모바일을 본다. 모바일은 Pixel 5를 쓴다.
iPhone 프리셋은 WebKit 기반이라 브라우저 바이너리를 하나 더 받아야 한다.

CI에서는 next dev 대신 빌드 결과를 실행한다. 경로마다 첫 진입에서 컴파일하는
탓에 느리고 결과가 흔들리던 문제가 사라진다. 같은 16건이 2.9분에서 49초로
줄었고, 병렬도 안정적이라 CI 워커를 2로 올렸다. 27.9초가 된다.
로컬은 dev 서버를 그대로 쓰므로 워커 1을 유지한다.

모바일과 PC 각각 16건 전부 통과하고 개발 DB 잔여 데이터가 없음을 확인했다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
develop과 main 대상 PR에서 Playwright 테스트를 실행한다. develop 대상은
모바일 뷰포트만 보고, 배포 직전인 main 대상에서만 PC 뷰포트를 함께 확인한다.
단위 테스트 워크플로와 별도 파일로 둔다.

- 문서만 바뀐 PR은 paths-ignore로 건너뛴다
- 같은 PR에 새 커밋이 오면 concurrency로 이전 실행을 취소한다
- 실패했을 때만 리포트와 trace를 산출물로 올린다. 보존 7일
- Chromium 하나만 설치한다. 두 프로젝트 모두 Chromium 기반이다

secrets 이름에는 E2E_를 붙여 운영 DB 값과 섞이지 않게 하고 워크플로 env에서
앱 환경변수 이름으로 연결한다. 키 이름은 Supabase의 현재 명칭인 publishable
key와 secret key를 따른다.

이름이 틀리면 값이 빈 문자열로 들어오고 테스트가 실패가 아니라 건너뛴 채
초록으로 끝난다. 그래서 빌드 전에 Check secrets 단계로 먼저 멈춘다.

env 파일을 모두 치우고 워크플로가 주입하는 값만으로 빌드와 테스트가 통과하는
것을 확인했다. 러너에는 .env.local이 없으므로 같은 조건이다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@vercel

vercel Bot commented Sep 1, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
nbread Ready Ready Preview Sep 1, 2026 10:59am UTC

# Conflicts:
#	llm-wiki/index.md
#	llm-wiki/log.md
첫 실행에서 checkout과 setup-node가 Node.js 20을 대상으로 해 러너가 강제로
Node.js 24에서 돌린다는 경고가 떴다. 세 액션 모두 현재 메이저인 v7로 올린다.

upload-artifact는 실패했을 때만 도는 단계라 이번 실행으로는 검증되지 않는다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@hm1n hm1n self-assigned this Sep 2, 2026
@hm1n hm1n added the 🧪 Test 테스트 코드 작성 및 테스트 환경 label Sep 2, 2026
@hm1n hm1n changed the title test: E2E 테스트 P0 15건 구현과 CI 게이트 추가 [test-79/e2e] 핵심 사용자 플로우 E2E 테스트 작성 Sep 2, 2026
@hm1n hm1n changed the title [test-79/e2e] 핵심 사용자 플로우 E2E 테스트 작성 [cicd-80/e2e] GitHub Actions E2E 테스트 워크플로우 추가 Sep 2, 2026
@hm1n hm1n added the 🔁 CI/CD CI/CD 및 운영 관련 작업 label Sep 2, 2026
@hm1n
hm1n marked this pull request as ready for review September 2, 2026 01:25
@hm1n

hm1n commented Sep 2, 2026

Copy link
Copy Markdown
Collaborator Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c829d6712d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

env:
NEXT_PUBLIC_SUPABASE_URL: ${{ secrets.E2E_SUPABASE_URL }}
NEXT_PUBLIC_SUPABASE_KEY: ${{ secrets.E2E_SUPABASE_PUBLISHABLE_KEY }}
SUPABASE_SERVICE_ROLE_KEY: ${{ secrets.E2E_SUPABASE_SECRET_KEY }}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Keep the service-role secret out of pull-request code

For same-repository pull requests, this job checks out the proposed merge commit and then runs its Playwright configuration, tests, and Next.js server with the Supabase service-role secret in the environment. Anyone permitted to open a branch PR can therefore add arbitrary Node or server code that transmits this key before the change is reviewed; because the key bypasses RLS, disclosure grants unrestricted access to the test project. Gate this privileged step behind a trusted environment approval or execute only trusted test code rather than passing the secret directly to candidate code.

AGENTS.md reference: AGENTS.md:L105-L109

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

유효한 지적입니다. 메커니즘을 확인했습니다.

pull_request 이벤트가 제안된 병합 커밋의 코드를 실행하고, 그 코드가 SUPABASE_SERVICE_ROLE_KEY가 든 환경에서 돌아가는 것이 맞습니다. fork PR을 배제한 설정은 이 경로를 막지 못합니다. 공격자가 fork가 아니라 같은 저장소의 브랜치를 쓰기 때문입니다.

이번 PR에서는 수용하고 #212로 분리했습니다.

노출되는 값은 개발 Supabase의 secret key 하나이고, 해당 프로젝트에는 실제 고객 데이터가 없습니다(user 행 4개). 악용 가능한 사람도 조직에 push 권한이 있는 인원으로 한정됩니다. 운영에는 닿지 않습니다.

제안하신 environment 승인 게이트는 검토했으나 선택하지 않았습니다. 노출은 막지만 매 PR마다 수동 승인이 생겨, 자동 게이트를 도입하는 이 PR의 목적과 정면으로 부딪힙니다.

구조를 바꾸는 것은 권한 자체를 좁히는 방식이라고 판단해 #212에서 다룹니다. seed와 cleanup을 서버 쪽 진입점 뒤로 옮기고, CI에는 E2E 테스트 계정과 그 데이터만 다룰 수 있는 자격증명만 두는 방향입니다.

다만 이 판단은 "개발 DB에 지킬 데이터가 없다"는 전제에 기대고 있어, 전제가 바뀌면 #212의 우선순위를 올려야 합니다. 수용 근거는 PR 본문에도 남겼습니다.

@hm1n
hm1n merged commit f63352b into develop Sep 2, 2026
3 checks passed
@hm1n
hm1n deleted the hm1n/e2e-test-case branch September 2, 2026 02:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🔁 CI/CD CI/CD 및 운영 관련 작업 🧪 Test 테스트 코드 작성 및 테스트 환경

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant